#include "Common.h"
#include "PatternInterpolation.h"
#include <stdio.h>
#include <string.h>

const unsigned pattern_mask = 0xFFFFF;
const unsigned pattern_array_size = 120;

const int REF_PIXEL_MAP_MATRIX[REF_PIXEL_NUMBER][2] = {
	{-3, -2}, {-1, -2}, { 1, -2}, { 3, -2},
	{ 3, -1}, { 3,  0}, { 3,  1}, { 3,  2},
	{ 1,  2}, {-1,  2}, {-3,  2}, {-3,  1},
	{-3,  0}, {-3, -1}, {-1, -1}, { 1, -1},
	{ 1,  0}, { 1,  1}, {-1,  1}, {-1,  0} 
};

unsigned int PATTERN_MATRIX[] = {
	0x1f000,
	0x1f000,
	0x7fc3f,
	0x7fc3f,
	0x3ff3f,
	0x780,
	0x3c000,
	0x7800,
	0x7800,
	0x3c000,
	0x780,
	0x3ff3f,
	0x3f81c,
	0x3f81c,
	0x3f81c,
	0x3f81c,
	0x7f81c,
	0x3fc1c,
	0x1f81c,
	0x3f01c,
	0x3f01c,
	0x1f81c,
	0x3fc1c,
	0x7f81c,
	0x7f01c,
	0x1fc1c,
	0x1fc1c,
	0x7f01c,
	0xfe0e,
	0x1fc7,
	0x1fc7,
	0xfe0e,
	0x7e0e,
	0x3fc7,
	0x1f87,
	0xff0e,
	0xff0e,
	0x1f87,
	0x3fc7,
	0x7e0e,
	0x1fc0e,
	0x7f038,
	0x7f038,
	0x1fc0e,
	0x3e010,
	0xf804,
	0x3fe1f,
	0x7c2,
	0x3f010,
	0x1f804,
	0x3fc1f,
	0x7f83d,
	0x7f018,
	0x1fc0c,
	0x1fc1e,
	0x7f03c,
	0x3f018,
	0x1f80c,
	0x3fc1e,
	0x7f83c,
	0x7e018,
	0xfc0c,
	0x1fe1e,
	0xfc3,
	0x7c04,
	0x7c010,
	0xf82,
	0x1ff1f,
	0x7e04,
	0x3fef,
	0x1f82,
	0xff1f,
	0x7c2,
	0x3fe1f,
	0xf804,
	0x3e010,
	0x7f83d,
	0x3fc1f,
	0x1f804,
	0x3f010,
	0xff0f,
	0x1f86,
	0x3fcf,
	0x7e06,
	0x3f8f,
	0x7f06,
	0x7f0f,
	0x3f86,
	0x7f8f,
	0x3f06,
	0x7f8f,
	0x3f06,
	0x7e06,
	0x3fcf,
	0x1f86,
	0xff0f,
	0x3f86,
	0x7f0f,
	0x7f06,
	0x3f8f,
	0x3f06,
	0x7f8f,
	0x3f06,
	0x7f8f,
	0x7f03c,
	0x1fc1e,
	0x1fc0c,
	0x7f018,
	0x7f83c,
	0x3fc1e,
	0x1f80c,
	0x3f018,
	0x1ff1f,
	0xf82,
	0x7c010,
	0x7c04,
	0x3f87,
	0x7f0e,
	0x7f0e,
	0x3f87
};

char COFF_MATRIX[][20] = {
	{ 0,-1,-3,0,0,0,0,0,-4,-4,0,0,0,0,71,15,5,15,69,68 },
	{ 0,-4,-4,0,0,0,0,0,-3,-1,0,0,0,0,69,15,5,15,71,68 },
	{ 0,-3,-1,0,0,0,0,0,-4,-4,0,0,0,0,15,71,68,69,15,5 },
	{ 0,-4,-4,0,0,0,0,0,-1,-3,0,0,0,0,15,69,68,71,15,5 },
	{ 0,0,-2,-1,1,0,0,0,0,-2,-1,2,0,0,2,14,8,0,15,6 },
	{ -1,-2,0,0,0,0,1,-1,-2,0,0,0,0,2,15,0,8,14,2,6 },
	{ -1,-2,0,0,0,0,2,-1,-2,0,0,0,0,1,14,2,6,15,0,8 },
	{ 0,0,-2,-1,2,0,0,0,0,-2,-1,1,0,0,0,15,6,2,14,8 },
	{ 0,0,-2,-2,0,0,0,0,0,-2,-2,0,0,0,0,15,0,0,15,0 },
	{ -2,-2,0,0,0,0,0,-2,-2,0,0,0,0,0,15,0,0,15,0,0 },
	{ -2,-2,0,0,0,0,0,-2,-2,0,0,0,0,0,15,0,0,15,0,0 },
	{ 0,0,-2,-2,0,0,0,0,0,-2,-2,0,0,0,0,15,0,0,15,0 },
	{ 0,-3,-4,0,0,0,0,0,-3,-4,0,0,0,0,15,15,1,15,14,4 },
	{ 0,-4,-3,0,0,0,0,0,-4,-3,0,0,0,0,14,15,1,15,15,4 },
	{ 0,-4,-3,0,0,0,0,0,-4,-3,0,0,0,0,15,15,4,14,15,1 },
	{ 0,-3,-4,0,0,0,0,0,-3,-4,0,0,0,0,15,14,4,15,15,1 },
	{ -4,-10,0,0,0,0,0,0,-4,-4,0,0,2,0,15,9,7,26,13,3 },
	{ 0,-4,-4,0,0,0,0,0,0,-10,-4,0,2,0,13,26,7,9,15,3 },
	{ 0,0,-10,-4,0,2,0,0,-4,-4,0,0,0,0,9,15,3,13,26,7 },
	{ 0,-4,-4,0,0,2,0,-4,-10,0,0,0,0,0,26,13,3,15,9,7 },
	{ 0,-4,-4,0,0,0,0,-4,-4,0,0,0,0,0,15,15,0,15,15,0 },
	{ 0,0,-4,-4,0,0,0,0,-4,-4,0,0,0,0,15,15,0,15,15,0 },
	{ 0,-4,-4,0,0,0,0,0,0,-4,-4,0,0,0,15,15,0,15,15,0 },
	{ -4,-4,0,0,0,0,0,0,-4,-4,0,0,0,0,15,15,0,15,15,0 },
	{ -2,-2,0,0,0,0,0,-1,-1,0,0,0,0,0,13,0,3,10,0,3 },
	{ 0,0,-1,-1,0,0,0,0,0,-2,-2,0,0,0,0,10,3,0,13,3 },
	{ 0,0,-2,-2,0,0,0,0,0,-1,-1,0,0,0,0,13,3,0,10,3 },
	{ -1,-1,0,0,0,0,0,-2,-2,0,0,0,0,0,10,0,3,13,0,3 },
	{ 0,0,0,-4,-1,0,0,0,0,0,-8,-1,0,0,0,8,14,0,13,15 },
	{ -8,0,0,0,0,0,-1,-4,0,0,0,0,0,-1,13,0,14,8,0,15 },
	{ -4,0,0,0,0,0,-1,-8,0,0,0,0,0,-1,8,0,15,13,0,14 },
	{ 0,0,0,-8,-1,0,0,0,0,0,-4,-1,0,0,0,13,15,0,8,14 },
	{ 0,0,0,0,-2,-4,0,0,0,0,-3,-1,0,0,0,4,14,0,6,15 },
	{ -3,0,0,0,0,-4,-2,0,0,0,0,0,0,-1,6,0,14,4,0,15 },
	{ 0,0,0,0,0,0,-1,-3,0,0,0,0,-4,-2,4,0,15,6,0,14 },
	{ 0,0,0,-3,-1,0,0,0,0,0,0,-2,-4,0,0,6,15,0,4,14 },
	{ 0,0,0,-4,-4,0,0,0,0,0,0,-4,-4,0,0,15,15,0,15,15 },
	{ 0,0,0,0,0,0,-4,-4,0,0,0,0,-4,-4,15,0,15,15,0,15 },
	{ -4,0,0,0,0,-4,-4,0,0,0,0,0,0,-4,15,0,15,15,0,15 },
	{ 0,0,0,0,-4,-4,0,0,0,0,-4,-4,0,0,0,15,15,0,15,15 },
	{ 0,0,0,-1,-4,0,0,0,0,0,-1,-4,0,0,0,9,15,0,9,14 },
	{ -1,0,0,0,0,0,-4,-1,0,0,0,0,0,-4,9,0,15,9,0,14 },
	{ -1,0,0,0,0,0,-4,-1,0,0,0,0,0,-4,9,0,14,9,0,15 },
	{ 0,0,0,-1,-4,0,0,0,0,0,-1,-4,0,0,0,9,14,0,9,15 },
	{ -1,-6,0,1,0,0,0,-1,-6,0,0,0,0,0,29,0,2,31,0,16 },
	{ 0,0,-6,-1,0,0,0,1,0,-6,-1,0,0,0,0,31,2,0,29,16 },
	{ 1,0,-6,-1,0,0,0,0,0,-6,-1,0,0,0,0,29,16,0,31,2 },
	{ -1,-6,0,0,0,0,0,-1,-6,0,1,0,0,0,31,0,16,29,0,2 },
	{ 0,-3,0,0,0,0,0,0,-1,0,0,0,0,0,30,0,1,27,1,48 },
	{ 0,0,-1,0,0,0,0,0,0,-3,0,0,0,0,1,27,1,0,30,48 },
	{ 0,0,-3,0,0,0,0,0,0,-1,0,0,0,0,0,30,48,1,27,1 },
	{ 0,-1,0,0,0,0,0,0,-3,0,0,0,0,0,27,1,48,30,0,1 },
	{ -6,-4,0,0,0,0,0,-4,-14,0,0,0,0,0,72,0,4,85,0,26 },
	{ 0,0,-14,-4,0,0,0,0,0,-4,-6,0,0,0,0,85,4,0,72,26 },
	{ 0,0,-4,-6,0,0,0,0,0,-14,-4,0,0,0,0,72,26,0,85,4 },
	{ -4,-14,0,0,0,0,0,-6,-4,0,0,0,0,0,85,0,26,72,0,4 },
	{ -26,-2,0,0,0,0,0,-2,-1,2,0,0,0,0,79,2,9,64,0,96 },
	{ 0,2,-1,-2,0,0,0,0,0,-2,-26,0,0,0,0,64,9,2,79,96 },
	{ 0,0,-2,-26,0,0,0,0,2,-1,-2,0,0,0,2,79,96,0,64,9 },
	{ -2,-1,2,0,0,0,0,-26,-2,0,0,0,0,0,64,0,96,79,2,9 },
	{ -1,-1,0,0,0,0,0,-1,-6,0,0,0,0,0,14,0,1,15,0,14 },
	{ 0,0,-6,-1,0,0,0,0,0,-1,-1,0,0,0,0,15,1,0,14,14 },
	{ 0,0,-1,-1,0,0,0,0,0,-6,-1,0,0,0,0,14,14,0,15,1 },
	{ -1,-6,0,0,0,0,0,-1,-1,0,0,0,0,0,15,0,14,14,0,1 },
	{ 0,0,0,31,-2,0,0,0,0,0,-50,62,0,0,0,102,63,0,10,115 },
	{ -50,0,0,0,0,0,-2,31,0,0,0,0,0,62,10,0,63,102,0,115 },
	{ 31,0,0,0,0,0,62,-50,0,0,0,0,0,-2,102,0,115,10,0,63 },
	{ 0,0,0,-50,62,0,0,0,0,0,31,-2,0,0,0,10,115,0,102,63 },
	{ -44,-4,0,0,32,0,1,-5,-5,0,0,64,1,0,3,60,27,0,0,124 },
	{ 0,0,-5,-5,1,0,32,0,0,-4,-44,0,1,64,0,0,27,60,3,124 },
	{ 0,0,-4,-44,0,1,64,0,0,-5,-5,1,0,32,60,3,124,0,0,27 },
	{ -5,-5,0,0,64,1,0,-44,-4,0,0,32,0,1,0,0,124,3,60,27 },
	{ -2,-2,0,0,0,0,0,-2,-2,0,0,0,0,0,15,0,0,15,0,0 },
	{ 0,0,-2,-2,0,0,0,0,0,-2,-2,0,0,0,0,15,0,0,15,0 },
	{ 0,0,-2,-2,0,0,0,0,0,-2,-2,0,0,0,0,15,0,0,15,0 },
	{ -2,-2,0,0,0,0,0,-2,-2,0,0,0,0,0,15,0,0,15,0,0 },
	{ 0,-4,0,0,0,0,0,0,-4,0,0,0,0,0,10,5,0,10,5,0 },
	{ 0,0,-4,0,0,0,0,0,0,-4,0,0,0,0,5,10,0,5,10,0 },
	{ 0,0,-4,0,0,0,0,0,0,-4,0,0,0,0,5,10,0,5,10,0 },
	{ 0,-4,0,0,0,0,0,0,-4,0,0,0,0,0,10,5,0,10,5,0 },
	{ 0,0,0,0,-1,0,0,0,0,0,6,-1,0,0,0,0,75,0,9,15 },
	{ 6,0,0,0,0,0,-1,0,0,0,0,0,0,-1,9,0,75,0,0,15 },
	{ 0,0,0,0,0,0,-1,6,0,0,0,0,0,-1,0,0,15,9,0,75 },
	{ 0,0,0,6,-1,0,0,0,0,0,0,-1,0,0,0,9,15,0,0,75 },
	{ 0,0,0,0,0,0,-3,0,0,0,0,0,-1,0,0,0,15,0,1,30 },
	{ 0,0,0,0,-3,0,0,0,0,0,0,0,-1,0,1,0,15,0,0,30 },
	{ 0,0,0,0,0,-1,0,0,0,0,0,-3,0,0,0,0,30,1,0,15 },
	{ 0,0,0,0,0,-1,0,0,0,0,0,0,0,-3,0,1,30,0,0,15 },
	{ 0,0,0,0,0,-1,1,0,0,0,0,0,-4,0,0,0,27,1,0,30 },
	{ 0,0,0,0,1,-1,0,0,0,0,0,0,-4,0,0,1,27,0,0,30 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,1,-1,0,0,0,30,0,1,27 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-1,1,1,0,30,0,0,27 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,0,-4,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,-4,0,0,0,0,15,0,0,15 },
	{ 0,0,0,0,-4,0,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,0,-4,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ 0,0,0,0,0,-4,0,0,0,0,0,0,-4,0,0,0,15,0,0,15 },
	{ -2,-2,0,0,0,0,0,-2,-2,0,0,0,0,0,15,0,0,15,0,0 },
	{ 0,0,-2,-2,0,0,0,0,0,-2,-2,0,0,0,0,15,0,0,15,0 },
	{ 0,0,-2,-2,0,0,0,0,0,-2,-2,0,0,0,0,15,0,0,15,0 },
	{ -2,-2,0,0,0,0,0,-2,-2,0,0,0,0,0,15,0,0,15,0,0 },
	{ 0,-4,0,0,0,0,0,0,-4,0,0,0,0,0,10,5,0,10,5,0 },
	{ 0,0,-4,0,0,0,0,0,0,-4,0,0,0,0,5,10,0,5,10,0 },
	{ 0,0,-4,0,0,0,0,0,0,-4,0,0,0,0,5,10,0,5,10,0 },
	{ 0,-4,0,0,0,0,0,0,-4,0,0,0,0,0,10,5,0,10,5,0 },
	{ 0,0,0,-4,-4,0,0,0,0,0,-4,-4,0,0,0,15,15,0,15,15 },
	{ -4,0,0,0,0,0,-4,-4,0,0,0,0,0,-4,15,0,15,15,0,15 },
	{ -4,0,0,0,0,0,-4,-4,0,0,0,0,0,-4,15,0,15,15,0,15 },
	{ 0,0,0,-4,-4,0,0,0,0,0,-4,-4,0,0,0,15,15,0,15,15 },
	{ 0,0,0,0,0,-4,-3,0,0,0,0,0,-4,-1,4,0,19,8,0,15 },
	{ 0,0,0,0,-3,-4,0,0,0,0,0,-1,-4,0,0,8,19,0,4,15 },
	{ 0,0,0,0,-1,-4,0,0,0,0,0,-3,-4,0,0,4,15,0,8,19 },
	{ 0,0,0,0,0,-4,-1,0,0,0,0,0,-4,-3,8,0,15,4,0,19 }
};


imgpel InterpolatePixelWithPattern(imgpel ** full_rec, int width, int height, int i, int j, int mb_x, int mb_y )
{
	int x = mb_x * width + i;
	int y = mb_y * height + j;

	unsigned char ref_pixel_array[REF_PIXEL_NUMBER];
	unsigned char result;

	if ( x < HORIZONTAL_SKIP_COUNT )
	{
		// the very left edge of the entire frame
		// x should be 1
		ref_pixel_array[0] = ref_pixel_array[1] = (unsigned char)full_rec[y][x-1];
		ref_pixel_array[2] = (unsigned char) full_rec[y][x+1];
		ref_pixel_array[3] = (unsigned char) full_rec[y][x+3];
		result = Compute4TapInterpolation( ref_pixel_array );
		// printf( "LEFT EDGE: X: %03d, Y: %03d", x, y );
	}
	else if ( i >= width - HORIZONTAL_SKIP_COUNT )
	{
		// printf( "RIGHT EDGE: X: %03d, Y: %03d", x, y );
		// the right edge of the macro block
		if ( i == 13 )
		{
			ref_pixel_array[0] = (unsigned char) full_rec[y][x-3];
			ref_pixel_array[1] = (unsigned char) full_rec[y][x-1];
			ref_pixel_array[2] = ref_pixel_array[3] = (unsigned char) full_rec[y][x+1];
			result = Compute4TapInterpolation( ref_pixel_array );
		}
		else
		{
			// i = 15
			ref_pixel_array[0] = (unsigned char) full_rec[y][x-3];
			ref_pixel_array[1] = (unsigned char) full_rec[y][x-1];
			ref_pixel_array[2] = ref_pixel_array[3] = (unsigned char) full_rec[y][x-1];
			result = Compute4TapInterpolation( ref_pixel_array );
		}
	}
	else if ( y < VERTICAL_SKIP_COUNT || j >= height - VERTICAL_SKIP_COUNT )
	{
		// the top line of the entire frame
		// printf( "TOP BOTTOM: X: %03d, Y: %03d", x, y );
		Get4TapRefPixelArray( x, y, ref_pixel_array, full_rec );
		result = Compute4TapInterpolation( ref_pixel_array );
	}
	else
	{
		// printf( "INNER AREA: X: %03d, Y: %03d", x, y );
		// the inner area
		GetRefPixelArray( x, y, ref_pixel_array, full_rec );

		// Check if flat area
		if ( CheckAreaFlat( ref_pixel_array ) )
		{
			// flat area
			Get4TapRefPixelArray( x, y, ref_pixel_array, full_rec );
			result = Compute4TapInterpolation( ref_pixel_array );
			
			// printf( "FLAT: X: %03d, Y: %03d", x, y );
		}
		else
		{
			// printf( "UNFT: X: %03d, Y: %03d", x, y );
			// unflat area, use patterns
			char pattern_array[REF_PIXEL_NUMBER];
			BinarizeRefPixelArray( pattern_array, ref_pixel_array );

			int pattern = PatternArrayToInt( pattern_array );
			pattern &= pattern_mask;
			pattern = NormalizePatternForm( pattern );

			bool find = false;
			int pattern_index = 0;

			for( int i=0; i<pattern_array_size; i++ )
			{
				if ( PATTERN_MATRIX[i] == pattern )
				{
					find = true;
					pattern_index = i;
					break;
				}
			}

			if ( find )
			{
				// find the match
				result = ComputeInterpolationPixel( ref_pixel_array, COFF_MATRIX[pattern_index] );
				// printf( "UNFT: X: %03d, Y: %03d INDEX: %03d", x, y, pattern_index );
			}
			else
			{
				// no match, use 4tap
				// printf( "UNFT: X: %03d, Y: %03d UNPATTERN", x, y );
				Get4TapRefPixelArray( x, y, ref_pixel_array, full_rec );
				result = Compute4TapInterpolation( ref_pixel_array );
			}
		}
	}

	return result;

}



unsigned int PatternArrayToInt( char * pattern_array )
{
	unsigned int pattern = 0;
	for ( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		pattern += pattern_array[REF_PIXEL_NUMBER-i-1] * (1<<i);
	}

	return pattern;
}

bool PatternIntToArray( unsigned int pattern, char * pattern_array )
{
	for ( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		pattern_array[REF_PIXEL_NUMBER-i-1] = (pattern&(1<<i)) == 0? 0:1;
	}

	return true;
}


bool GetRefPixelArray( int x, int y, unsigned char * ref_pixel_array,  imgpel ** frame )
{

	for( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		ref_pixel_array[i] = frame[ (y+REF_PIXEL_MAP_MATRIX[i][1]) ][ x+REF_PIXEL_MAP_MATRIX[i][0] ];
	}

	return true;
}

bool Get4TapRefPixelArray( int x, int y, unsigned char * ref_pixel_array, imgpel ** frame )
{

	for( int i=0; i<4; i++ )
	{
		ref_pixel_array[i] = frame[y][x+REF_4TAP_PIXEL_MATRIX[i]];
	}

	return true;
}

unsigned char ComputeInterpolationPixel( unsigned char * ref_pixel_array, char * coff_array )
{
	int result = 0;
	int factor = 0;
	for ( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		result += coff_array[i] * ref_pixel_array[i];
		factor += coff_array[i];
	}

	result = (result+factor/2) / factor;

	if ( result < 0 ) result = 0;
	if ( result > 255 ) result = 255;

	return static_cast<unsigned char>( result );
}

unsigned char Compute4TapInterpolation( unsigned char * ref_pixel_array )
{
	int result = 0;
	for ( int i=0; i<4; i++ )
	{
		result += REF_4TAP_COFF[i] * ref_pixel_array[i];
	}

	result += REF_4TAP_COFF_SUM/2;
	result /= REF_4TAP_COFF_SUM;

	if ( result < 0 ) result = 0;
	if ( result > 255 ) result = 255;

	return static_cast<unsigned char>( result );
}


unsigned int NormalizePatternForm( unsigned int pattern )
{
	if ( (pattern & NORMAL_TEST_BIT) == 0 )
	{
		return pattern;
	}
	else
	{
		return (~pattern) & PATTERN_VALID_BITMASK;
	}
}


unsigned int GetPatternBit( unsigned int pattern, int i )
{
	return pattern & (1<<(REF_PIXEL_NUMBER-1-i));
}

bool CheckAreaFlat( unsigned char * ref_pixel_array )
{
	// TODO: mask?
	int max = 0;
	int min = 256;

	for ( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		if ( max < ref_pixel_array[i] ) max = ref_pixel_array[i];
		if ( min > ref_pixel_array[i] ) min = ref_pixel_array[i];
	}

	if ( max - min < FLAT_THRESHOLD_VALUE ) 
	{
		return true;
	}
	else
	{
		return false;
	}
}


bool BinarizeRefPixelArray( char * pattern_array, unsigned char * ref_pixel_array )
{
	int sum = 0;
	int count = 0;
	for ( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		if ( GetPatternBit( pattern_mask, i ) != 0 )
		{
			sum += ref_pixel_array[i];
			count++;
		}
	}
	sum = sum/count;

	for ( int i=0; i<REF_PIXEL_NUMBER; i++ )
	{
		if ( GetPatternBit( pattern_mask, i ) != 0 )
		{
			pattern_array[i] = (ref_pixel_array[i] > sum)? 1:0;
		}
	}

	return true;
}